from datetime import datetime, timedelta
from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from app.models.device import Device, DeviceLog
from app.models.treatment import TreatmentRecord
from app.extensions import db
from app.utils.decorators import handle_errors
from app.utils.bluetooth_protocol import BluetoothProtocol

devices_bp = Blueprint('devices', __name__, url_prefix='/api/devices')


@devices_bp.route('', methods=['GET'])
@jwt_required()
@handle_errors
def get_devices():
    """获取设备列表"""
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    status = request.args.get('status')
    
    query = Device.query
    if status:
        query = query.filter(Device.status == status)
    
    total = query.count()
    devices = query.offset((page - 1) * limit).limit(limit).all()
    
    return jsonify({
        'devices': [device.to_dict() for device in devices],
        'total': total,
        'page': page,
        'limit': limit
    })


@devices_bp.route('/<device_id>/status', methods=['GET'])
@jwt_required()
@handle_errors
def get_device_status(device_id):
    """获取设备状态"""
    device = Device.query.filter_by(device_id=device_id).first()
    
    if not device:
        return jsonify({'error': '设备不存在'}), 404
    
    # 获取设备最近的治疗记录
    recent_treatment = TreatmentRecord.query.filter_by(
        device_id=device_id
    ).order_by(TreatmentRecord.created_at.desc()).first()
    
    return jsonify({
        'device': device.to_dict(),
        'recent_treatment': recent_treatment.to_dict() if recent_treatment else None
    })


@devices_bp.route('/<device_id>/heartbeat', methods=['POST'])
@jwt_required()
@handle_errors
def device_heartbeat(device_id):
    """设备心跳更新"""
    current_user_id = get_jwt_identity()
    data = request.get_json()
    
    device = Device.query.filter_by(device_id=device_id).first()
    if not device:
        # 自动注册新设备
        device = Device(
            device_id=device_id,
            device_name=data.get('device_name', 'MDK_001'),
            firmware_version=data.get('firmware_version')
        )
        db.session.add(device)
    
    # 更新心跳信息
    device.update_heartbeat(
        battery_level=data.get('battery_level'),
        user_id=current_user_id
    )
    
    # 记录设备日志
    log = DeviceLog(
        device_id=device_id,
        user_id=current_user_id,
        action='heartbeat',
        data={
            'battery_level': data.get('battery_level'),
            'signal_strength': data.get('signal_strength')
        }
    )
    db.session.add(log)
    db.session.commit()
    
    return jsonify({
        'message': '心跳更新成功',
        'device': device.to_dict()
    })


@devices_bp.route('/<device_id>/connect', methods=['POST'])
@jwt_required()
@handle_errors
def connect_device(device_id):
    """连接设备"""
    current_user_id = get_jwt_identity()
    
    device = Device.query.filter_by(device_id=device_id).first()
    if not device:
        return jsonify({'error': '设备不存在'}), 404
    
    # 检查设备是否已被其他用户连接
    if device.status == 'online' and device.last_user_id != current_user_id:
        return jsonify({'error': '设备已被其他用户连接'}), 409
    
    # 更新设备状态
    device.status = 'online'
    device.last_user_id = current_user_id
    device.last_heartbeat = datetime.utcnow()
    
    # 记录连接日志
    log = DeviceLog(
        device_id=device_id,
        user_id=current_user_id,
        action='connect'
    )
    db.session.add(log)
    db.session.commit()
    
    return jsonify({
        'message': '设备连接成功',
        'device': device.to_dict()
    })


@devices_bp.route('/<device_id>/disconnect', methods=['POST'])
@jwt_required()
@handle_errors
def disconnect_device(device_id):
    """断开设备连接"""
    current_user_id = get_jwt_identity()
    
    device = Device.query.filter_by(device_id=device_id).first()
    if not device:
        return jsonify({'error': '设备不存在'}), 404
    
    # 只有连接的用户才能断开
    if device.last_user_id != current_user_id:
        return jsonify({'error': '无权限断开此设备'}), 403
    
    device.status = 'offline'
    
    # 记录断开日志
    log = DeviceLog(
        device_id=device_id,
        user_id=current_user_id,
        action='disconnect'
    )
    db.session.add(log)
    db.session.commit()
    
    return jsonify({
        'message': '设备断开成功'
    })


@devices_bp.route('/<device_id>/command', methods=['POST'])
@jwt_required()
@handle_errors
def send_device_command(device_id):
    """发送设备命令"""
    current_user_id = get_jwt_identity()
    data = request.get_json()
    
    device = Device.query.filter_by(device_id=device_id).first()
    if not device:
        return jsonify({'error': '设备不存在'}), 404
    
    if device.last_user_id != current_user_id:
        return jsonify({'error': '无权限控制此设备'}), 403
    
    command = data.get('command')
    params = data.get('params', {})
    
    # 使用蓝牙协议处理命令
    protocol = BluetoothProtocol()
    
    try:
        if command == 'set_mode':
            # 设置治疗模式
            response = protocol.set_treatment_mode(params.get('mode'))
        elif command == 'set_intensity':
            # 设置电流强度
            response = protocol.set_current_intensity(params.get('intensity'))
        elif command == 'set_duration':
            # 设置治疗时间
            response = protocol.set_treatment_duration(params.get('duration'))
        elif command == 'start_treatment':
            # 开始治疗
            response = protocol.start_treatment()
        elif command == 'stop_treatment':
            # 停止治疗
            response = protocol.stop_treatment()
        elif command == 'pause_treatment':
            # 暂停治疗
            response = protocol.pause_treatment()
        else:
            return jsonify({'error': '未知命令'}), 400
        
        # 记录命令日志
        log = DeviceLog(
            device_id=device_id,
            user_id=current_user_id,
            action=f'command_{command}',
            data={'params': params, 'response': response}
        )
        db.session.add(log)
        db.session.commit()
        
        return jsonify({
            'message': '命令发送成功',
            'response': response
        })
        
    except Exception as e:
        return jsonify({'error': f'命令执行失败: {str(e)}'}), 500


@devices_bp.route('/<device_id>/logs', methods=['GET'])
@jwt_required()
@handle_errors
def get_device_logs(device_id):
    """获取设备日志"""
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 50, type=int)
    action = request.args.get('action')
    
    query = DeviceLog.query.filter_by(device_id=device_id)
    if action:
        query = query.filter(DeviceLog.action == action)
    
    query = query.order_by(DeviceLog.created_at.desc())
    total = query.count()
    logs = query.offset((page - 1) * limit).limit(limit).all()
    
    return jsonify({
        'logs': [log.to_dict() for log in logs],
        'total': total,
        'page': page,
        'limit': limit
    })


@devices_bp.route('/statistics', methods=['GET'])
@handle_errors
def get_device_statistics():
    """获取设备统计信息"""
    # 设备状态统计
    status_stats = db.session.query(
        Device.status,
        db.func.count(Device.id).label('count')
    ).group_by(Device.status).all()
    
    # 设备使用统计（最近30天）
    thirty_days_ago = datetime.utcnow() - timedelta(days=30)
    usage_stats = db.session.query(
        db.func.date(DeviceLog.created_at).label('date'),
        db.func.count(db.distinct(DeviceLog.device_id)).label('active_devices')
    ).filter(
        DeviceLog.created_at >= thirty_days_ago
    ).group_by(db.func.date(DeviceLog.created_at)).all()
    
    # 电池电量分布
    battery_stats = db.session.query(
        Device.battery_level,
        db.func.count(Device.id).label('count')
    ).filter(Device.battery_level.isnot(None)).group_by(Device.battery_level).all()
    
    return jsonify({
        'status_distribution': [{'status': status, 'count': count} for status, count in status_stats],
        'daily_usage': [{'date': str(date), 'active_devices': count} for date, count in usage_stats],
        'battery_distribution': [{'level': level, 'count': count} for level, count in battery_stats],
        'total_devices': Device.query.count(),
        'online_devices': Device.query.filter_by(status='online').count()
    })


@devices_bp.route('/<device_id>/lock', methods=['POST'])
@jwt_required()
@handle_errors
def lock_device(device_id):
    """锁定设备"""
    # 检查是否为管理员
    # 这里应该添加权限检查逻辑
    
    device = Device.query.filter_by(device_id=device_id).first()
    if not device:
        return jsonify({'error': '设备不存在'}), 404
    
    device.is_locked = True
    db.session.commit()
    
    # 记录设备日志
    log = DeviceLog(
        device_id=device_id,
        action='lock',
        data={'status': 'locked'}
    )
    db.session.add(log)
    db.session.commit()
    
    return jsonify({
        'message': '设备已锁定',
        'device': device.to_dict()
    })


@devices_bp.route('/<device_id>/unlock', methods=['POST'])
@jwt_required()
@handle_errors
def unlock_device(device_id):
    """解锁设备"""
    # 检查是否为管理员
    # 这里应该添加权限检查逻辑
    
    device = Device.query.filter_by(device_id=device_id).first()
    if not device:
        return jsonify({'error': '设备不存在'}), 404
    
    device.is_locked = False
    db.session.commit()
    
    # 记录设备日志
    log = DeviceLog(
        device_id=device_id,
        action='unlock',
        data={'status': 'unlocked'}
    )
    db.session.add(log)
    db.session.commit()
    
    return jsonify({
        'message': '设备已解锁',
        'device': device.to_dict()
    })


@devices_bp.route('/<device_id>/maintenance', methods=['POST'])
@jwt_required()
@handle_errors
def set_maintenance_mode(device_id):
    """设置设备维护模式"""
    data = request.get_json()
    maintenance = data.get('maintenance', True)
    
    device = Device.query.filter_by(device_id=device_id).first()
    if not device:
        return jsonify({'error': '设备不存在'}), 404
    
    device.status = 'maintenance' if maintenance else 'offline'
    db.session.commit()
    
    # 记录设备日志
    log = DeviceLog(
        device_id=device_id,
        action='maintenance',
        data={'maintenance': maintenance}
    )
    db.session.add(log)
    db.session.commit()
    
    status_text = '维护模式已开启' if maintenance else '维护模式已关闭'
    return jsonify({
        'message': status_text,
        'device': device.to_dict()
    })
